home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
lang_asm
/
asm_kit
/
scrnsave.asm
< prev
next >
Wrap
Assembly Source File
|
1985-08-05
|
9KB
|
250 lines
;-----------------------------------------------------------------------------;
; These are the interrupt vectors for the clock, keyboard, and video ;
; io calls. ;
;-----------------------------------------------------------------------------;
vectors segment at 0h
org 10h * 2
time_of_day_vector1 label word ;clock interrupt, 18.2 per second
org 11h * 2
time_of_day_vector2 label word
org 12h * 2
keyboard_int_vector1 label word
org 13h * 2
keyboard_int_vector2 label word
org 20h * 2
video_io_vector1 label word
org 21h * 2
video_io_vector2 label word
vectors ends
;-----------------------------------------------------------------------------;
; This is the data area starting at 400h used by the ROM BIOS ;
; routines. ADDR_6845 contains the base address, 3x4, of the current ;
; display adapter and CRT_MODE_SET contains the current setting of the ;
; display mode - the 3x8 register. Here x is B for the monochrome ;
; display adapter, and D for the color-graphics adapter. ;
;-----------------------------------------------------------------------------;
rom_bios_data segment at 40h
org 10h
equip_flag dw ? ;used to determine display type
org 60h
cursor_mode dw ? ;current cursor mode (start, stop line)
org 63h
addr_6845 dw ? ;base address for active display card
crt_mode_set db ? ;current setting of 3x8 register
rom_bios_data ends
;-----------------------------------------------------------------------------;
; this is the start of the local data and executable code ;
;-----------------------------------------------------------------------------;
code_seg segment
assume cs:code_seg
org 100h
begin: jmp init_vectors ;initialize vectors and attach to DOS
rom_time_of_day_int1 dw ? ;addresses for rom routines
rom_time_of_day_int2 dw ?
rom_keyboard_int1 dw ?
rom_keyboard_int2 dw ?
rom_video_io_int1 dw ?
rom_video_io_int2 dw ?
timer_delay dw 0ccch ;delay before turning off video
three_min_counter dw ? ;clock ticks in three minutes
old_cursor_type dw 0 ;hold the old cursor type
;-----------------------------------------------------------------------------;
; turn the video display off after three minutes of no use. ;
; ;
; calls: rom_time_of_day_int ;
; reads: addr_6845, crt_set_mode ;
; writes: three_min_counter, old_cursor_type ;
;-----------------------------------------------------------------------------;
intercept_time_of_day proc near
push ax
push ds
mov ax, cs ;set data segment to current segment
mov ds, ax
assume ds:code_seg
dec three_min_counter ;Have 3 minutes elapsed
jz turn_video_off ;yes, turn video off
jg goto_rom_time_of_day ;no, keep video on
mov three_min_counter, 0 ;video is off, reset cnt
goto_rom_time_of_day:
pop ds
pop ax
assume ds:nothing
jmp rom_time_of_day_int1
turn_video_off:
assume ds:code_seg
push bx
push cx
push dx
mov ah, 3 ;get current cursor type into CX
pushf ;push flags to simulate INT with CALL
call rom_video_io_int1 ;must use call since INT 10 points here
mov old_cursor_type, cx ;and save it.
mov ch, 0fh ;now remove cursor from screen
mov cl, 0
mov ah, 1
pushf
call rom_video_io_int1
pop dx
pop cx
pop bx
push dx
mov ax, rom_bios_data
mov ds, ax
assume ds:rom_bios_data
mov dx, addr_6845 ;get base address for display adapter
add dx, 4 ;IO address for 3x8 register
mov al, crt_mode_set
and al, 0f7h ;turn video off
out dx, al
pop dx
jmp goto_rom_time_of_day
intercept_time_of_day endp
;-----------------------------------------------------------------------------;
; This procedure resets the timer count to 0ccch and turns the display ;
; on if it was off. ;
;-----------------------------------------------------------------------------;
reset_counter proc near
push ax
push dx
push ds
mov ax, cs
mov ds, ax
assume ds:code_seg
cmp three_min_counter, 0 ;was the display off?
jg video_not_off ;no, then reset counter
push ds ;yes, then turn video back on
mov ax, rom_bios_data
mov ds, ax
assume ds:rom_bios_data
mov dx, addr_6845 ;get base address for display adapter
add dx, 4 ;IO address for 3x8 register
mov al, crt_mode_set
or al, 8 ;turn video on again
out dx, al
pop ds
assume ds:code_seg
push cx ;now restore the cursor
mov cx, old_cursor_type
mov ah, 1 ;restore the old cursor type
pushf
call rom_video_io_int1
pop cx
video_not_off:
mov ax, timer_delay
mov three_min_counter, ax
pop ds
pop dx
pop ax
ret
reset_counter endp
intercept_keyboard_int proc near
assume ds:nothing
call reset_counter ;reset the timeout counter
jmp rom_keyboard_int1 ;pass control to rom routine
intercept_keyboard_int endp
;-----------------------------------------------------------------------------;
; This procedure resets the cursor type to the default type for the ;
; display adapter in use: 607H for the color/graphics adapter and ;
; 0B0CH for the monochrome display adapter. ;
;-----------------------------------------------------------------------------;
set_cursor_mode proc near
push ax
push cx
push ds
mov ax, rom_bios_data
mov ds, ax ;point to ROM BIOS data area
assume ds:rom_bios_data
mov ax, equip_flag ;determine which adapter is active
and al, 30h ;isolate adapter information
mov cx, 607h ;set for color/graphics adapter
cmp al, 30h ;is monochrome display active
jne color_active ;no, set cursor type
mov cx, 0B0Ch ;cursor mode for monochrome display
color_active:
mov ah, 1
pushf
call rom_video_io_int1
pop ds
pop cx
pop ax
ret
set_cursor_mode endp
;-----------------------------------------------------------------------------;
; This procedure resets the time-out counter, and passes control on ;
; to the ROM_VIDEO_IO routines. ;
;-----------------------------------------------------------------------------;
intercept_video_io proc near
assume ds:nothing
call reset_counter ;reset time-out counter
pushf
call rom_video_io_int1
or ah, ah ;asking for set-mode function?
jnz not_mode_set ;no, then return
call set_cursor_mode ;yes, then set cursor mode to default
not_mode_set:
iret
intercept_video_io endp
;-----------------------------------------------------------------------------;
; This procedure initializes the interrupt vectors. ;
;-----------------------------------------------------------------------------;
init_vectors proc near
assume ds:vectors
mov ax, vectors ;set up the data segment for vectors
mov ds, ax
cli ;don't allow interrupts
mov ax, time_of_day_vector1 ;save addr / BIOS routine
mov rom_time_of_day_int1, ax
mov ax, time_of_day_vector2
mov rom_time_of_day_int2, ax
mov time_of_day_vector1, offset intercept_time_of_day
mov time_of_day_vector2, cs
mov ax, keyboard_int_vector1
mov rom_keyboard_int1, ax
mov ax, keyboard_int_vector2
mov rom_keyboard_int2, ax
mov keyboard_int_vector1, offset intercept_keyboard_int
mov keyboard_int_vector2, cs
mov ax, video_io_vector1
mov rom_video_io_int1, ax
mov ax, video_io_vector2
mov rom_video_io_int2, ax
mov video_io_vector1, offset intercept_video_io
mov video_io_vector2, cs
mov ax, timer_delay ;set the delay to 3 minutes
mov three_min_counter, ax
sti ;allow interrupts again
call set_cursor_mode ;set cursor mode to default
mov dx, offset init_vectors ;end of resident portion
int 27h ;terminate but stay resident
init_vectors endp
code_seg ends
end begin